﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InductBase;
using SharpBolt.BasicIntefaces;
using SharpBolt.Graphics;
using SharpBolt.Basics;
using TestGame.GraphicUtilites;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
using OpenTK;


namespace TestGame
{
    class OpenGLRender : IGraphicRender
    {
        Dictionary<string, OpenGLBitmap> Bitmaps;

        uint uk = 0;
        public uint GetUK() { return uk++;}

        public Vec2i ScreenSize { get; set; }
        public Rec View { get; set; }

        public System.Drawing.Rectangle ClientRectangle;

        public OpenGLRender()
        {
            Bitmaps = new Dictionary<string, OpenGLBitmap>();
            View = new Rec(0, 0, 640, 480);
        }

        public SharpBolt.Basics.bBitmap GetBitmap(string name) {
            
            if (Bitmaps.ContainsKey(name))
                return Bitmaps[name];

            
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(name);
            Texture tex = new Texture(bmp);

            OpenGLBitmap result = new OpenGLBitmap(
                Vec2i.FromSize(bmp.Size),
                GetUK(),
                tex
                );           

            Bitmaps.Add(name, result);
            return result;
        }
        public void FreeBitmap(string name) {
            if (!Bitmaps.ContainsKey(name)) return;
            (Bitmaps[name].Data as Texture).Dispose();
            Bitmaps.Remove(name);
        }

        public void BeginDraw() {
            GL.ClearColor(Color4.Magenta);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            var Projection = Matrix4.CreateOrthographic(-ClientRectangle.Width, -ClientRectangle.Height, -1, 1);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref Projection);
            GL.Translate(ClientRectangle.Width * 0.5, -ClientRectangle.Height * 0.5, 0);

            var Modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref Modelview);
        }

        public void EndDraw() { }
        public void Draw(SharpBolt.Basics.bBitmap bitmap, Vec2 position, Vec2 scale, Vec2 shift, double rotation, Color color, Rec blit)
        {
            GL.PushMatrix();
            GL.Translate(View.Position.X, View.Position.Y, 0);
            Vec2 viewScale = ScreenSize / View.Size;
            GL.Scale(viewScale.X, viewScale.Y, 1);


            GL.PushMatrix();
            GL.Translate(position.X, position.Y,0);
            GL.Rotate(rotation, 0, 0, 1);
            GL.Scale(scale.X, scale.Y, 1);
            GL.Translate(shift.X, shift.Y, 1);
            OpenGLBitmap obitmap = bitmap as OpenGLBitmap;
 
            obitmap.tex.Bind();

            float toFlt = 1.0f / 255f;
            GL.Color4(new Color4(color.R * toFlt, color.G * toFlt, color.B * toFlt, color.A * toFlt));            
            GL.Begin(BeginMode.Quads);
            Rec coords = new Rec(0, 0, 1, 1);
            coords.Position = (Vec2)blit.Position / (Vec2)bitmap.Size;
            coords.Size = (Vec2)blit.Size / (Vec2)bitmap.Size;


            Rec quad = Rec.FromLocationSize(Vec2.Null,blit.Size);

            GL.TexCoord2(coords.Min.X, coords.Max.Y);
            GL.Vertex2(quad.Min.X, quad.Max.Y);

            GL.TexCoord2(coords.Min.X, coords.Min.Y);
            GL.Vertex2(quad.Min.X, quad.Min.Y);

            GL.TexCoord2(coords.Max.X, coords.Min.Y);
            GL.Vertex2(quad.Max.X, quad.Min.Y);

            GL.TexCoord2(coords.Max.X, coords.Max.Y);
            GL.Vertex2(quad.Max.X, quad.Max.Y);

            
            GL.End();

            GL.PopMatrix();
            GL.PopMatrix();
        }
       
    }
}
